﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.Xml;

using System.Security;
using System.Security.AccessControl;
using Microsoft.Win32;


namespace FailoverClusterController
{
    [RunInstaller(true)]
    public partial class ProjectInstaller : System.Configuration.Install.Installer
    {
        public ProjectInstaller()
        {
            InitializeComponent();
        }

        // Override the 'Install' method.
        public override void Install(IDictionary savedState)
        {
            base.Install(savedState);

            try
            {
                // In order to get the value from the textBox named 'OPNIC' I needed to add the line:
                // '/NICVAL = [OPNIC]' to the CustomActionData property of the CustomAction We added. 
                string NICval = Context.Parameters["NICVAL"];

                // Get the path to the executable file that is being installed on the target computer
                string assemblypath = Context.Parameters["assemblypath"];
                string appConfigPath = assemblypath + ".config";

                // Write the path to the app.config file
                XmlDocument doc = new XmlDocument();
                doc.Load(appConfigPath);

                XmlNode configuration = null;
                foreach (XmlNode node in doc.ChildNodes)
                    if (node.Name == "configuration")
                        configuration = node;

                if (configuration != null)
                {
                    // Get the 'appSettings' node
                    XmlNode settingNode = null;
                    foreach (XmlNode node in configuration.ChildNodes)
                        if (node.Name == "appSettings")
                            settingNode = node;

                    if (settingNode != null)
                    {
                        // Get the node with the attribute key="FilePath"
                        XmlNode NumNode = null;
                        foreach (XmlNode node in settingNode.ChildNodes)
                        {
                            if (node.Attributes["key"] != null)
                                if (node.Attributes["key"].Value == "NIC")
                                    NumNode = node;
                        }

                        if (NumNode != null)
                        {
                            XmlAttribute att = NumNode.Attributes["value"];
                            att.Value = NICval; // Update the configuration file

                            // Save the configuration file
                            doc.Save(appConfigPath);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message, e.Source);
            }


            if (!(Environment.UserName == "Administrator" || Environment.UserName == "administrator"))
            {
                System.Windows.Forms.MessageBox.Show("Warning:\nYou are installing ViCOS Failover Controller with an user different from Administrator.\nBe sure that the user is part of the Domain Administrators Group");
            }
            if (Environment.UserDomainName == Environment.MachineName)
            {
                System.Windows.Forms.MessageBox.Show("Warning:\nYou are using a Local User, ViCOS Failover Controller must be installed with Domain Administrator Privileges");
            }


            ExecuteCommandSync("DISM /online /enable-feature /featurename:NetFx2-ServerCore");
            ExecuteCommandSync("DISM /online /enable-feature /featurename:NetFx3-ServerCore");
            ExecuteCommandSync("DISM /online /enable-feature /featurename:NetFx2-ServerCore-WOW64");
            ExecuteCommandSync("DISM /online /enable-feature /featurename:NetFx3-ServerCore-WOW64");
            ExecuteCommandSync("DISM /online /enable-feature /featurename:MicrosoftWindowsPowerShell-WOW64");


            //string user = Environment.UserDomainName + "\\" + Environment.UserName;
            //string regPath = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog";
            //RegistryKey regKey = null;

            //try
            //{
            //    RegistrySecurity regSecurity = new RegistrySecurity();
            //    regSecurity.AddAccessRule(new RegistryAccessRule(user, RegistryRights.WriteKey | RegistryRights.FullControl, InheritanceFlags.ContainerInherit, PropagationFlags.InheritOnly, AccessControlType.Allow));

            //    regKey = Registry.LocalMachine.OpenSubKey(regPath, false);
            //    regKey.SetAccessControl(regSecurity);
            //}
            //catch (UnauthorizedAccessException ex)
            //{
            //    System.Windows.Forms.MessageBox.Show(String.Format("Unable to change permissions for the Registry Key {0} key. Caught UnauthorizedAccessException: {1}", regPath, ex.Message));
            //}
            //catch (Exception ex)
            //{
            //    System.Windows.Forms.MessageBox.Show(String.Format("Unexpected Exception:\n{0}", ex.Message));
            //}

            //regKey.Close();
        }

        /// <summary>
        /// Executes a shell command synchronously.
        /// </summary>
        /// <param name="command">string command</param>
        /// <returns>string, as output of the command.</returns>
        public void ExecuteCommandSync(object command)
        {
            try
            {
                // create the ProcessStartInfo using "cmd" as the program to be run,
                // and "/c " as the parameters.
                // Incidentally, /c tells cmd that we want it to execute the command that follows,
                // and then exit.
                System.Diagnostics.ProcessStartInfo procStartInfo =
                    new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);

                // The following commands are needed to redirect the standard output.
                // This means that it will be redirected to the Process.StandardOutput StreamReader.
                procStartInfo.RedirectStandardOutput = true;
                procStartInfo.UseShellExecute = false;
                // Do not create the black window.
                procStartInfo.CreateNoWindow = true;
                // Now we create a process, assign its ProcessStartInfo and start it
                System.Diagnostics.Process proc = new System.Diagnostics.Process();
                proc.StartInfo = procStartInfo;
                proc.Start();
                // Get the output into a string
                string result = proc.StandardOutput.ReadToEnd();
                // Display the command output.
                //Console.WriteLine(result);
            }
            catch (Exception objException)
            {
                System.Windows.Forms.MessageBox.Show(String.Format("Prerequisites Installation Error:\n{0}", objException.Message));
            }
        }
    }
}
